package org.jeecg.modules.app.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.getui.push.v2.sdk.ApiHelper;
import com.getui.push.v2.sdk.GtApiConfiguration;
import com.getui.push.v2.sdk.api.PushApi;
import com.getui.push.v2.sdk.common.ApiResult;
import com.getui.push.v2.sdk.dto.req.Audience;
import com.getui.push.v2.sdk.dto.req.Settings;
import com.getui.push.v2.sdk.dto.req.message.PushBatchDTO;
import com.getui.push.v2.sdk.dto.req.message.PushChannel;
import com.getui.push.v2.sdk.dto.req.message.PushDTO;
import com.getui.push.v2.sdk.dto.req.message.PushMessage;
import com.getui.push.v2.sdk.dto.req.message.android.AndroidDTO;
import com.getui.push.v2.sdk.dto.req.message.android.ThirdNotification;
import com.getui.push.v2.sdk.dto.req.message.android.Ups;
import com.getui.push.v2.sdk.dto.req.message.ios.Alert;
import com.getui.push.v2.sdk.dto.req.message.ios.Aps;
import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO;
import org.jeecg.modules.app.entity.AppPushRecord;
import org.jeecg.modules.app.enums.AppPlatformTypeEnums;
import org.jeecg.modules.app.mapper.AppPushRecordMapper;
import org.jeecg.modules.app.service.IAppPushRecordService;
import org.jeecg.modules.app.service.IPushMessageService;
import org.jeecg.modules.app.vo.PushTargetVO;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.text.MessageFormat;
import java.util.List;

/**
 * @Description: app_push_record
 * @Author: jeecg-boot
 * @Date:   2024-12-17
 * @Version: V1.0
 */
@Service
public class AppPushRecordServiceImpl extends ServiceImpl<AppPushRecordMapper, AppPushRecord> implements IAppPushRecordService, IPushMessageService {

    private final String intent_pattern = "intent://io.dcloud.unipush/?#Intent;scheme=unipush;launchFlags=0x4000000;component={0}/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title={1};S.content={2};S.payload={3};end";

    private String initIntent(String packageName, AppPushRecord message){
        String intent = MessageFormat.format(intent_pattern, packageName, message.getTitle(), message.getContent(), message.getPayload());
        return intent;
    }

    private PushApi initPushApi(JsonNode config){
        GtApiConfiguration apiConfiguration = new GtApiConfiguration();
        //填写应用配置，参数在“Uni Push”下的“应用配置”页面中获取
        apiConfiguration.setAppId(config.get("appId").asText());
        apiConfiguration.setAppKey(config.get("appKey").asText());
        apiConfiguration.setMasterSecret(config.get("masterSecret").asText());
//        apiConfiguration.setDomain(config.get("domain").asText());
//        apiConfiguration.setAppId("w2YvnG3HdI8ZnDviM4FukA");
//        apiConfiguration.setAppKey("ORF9nyymr17Kg70VlksH29");
//        apiConfiguration.setMasterSecret("HS80Lj8fvu7liUtATVBK39");
        // 实例化ApiHelper对象，用于创建接口对象
        ApiHelper apiHelper = ApiHelper.build(apiConfiguration);
        // 创建对象，建议复用。目前有PushApi、StatisticApi、UserApi
        PushApi pushApi = apiHelper.creatApi(PushApi.class);
        return pushApi;
    }

    @Override
    public JsonNode push(PushTargetVO target, JsonNode config, AppPushRecord message) throws JsonProcessingException {
        PushApi pushApi = initPushApi(config);
        PushDTO pushDTO = createPushDTO(target, config, message); //构建推送消息目标
        // 进行cid单推
        ApiResult apiResult = pushApi.pushToSingleByCid(pushDTO);
        if (apiResult.isSuccess()) {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.valueToTree(apiResult.getData());
        } else {
            throw new RuntimeException("code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
        }
    }

    @Override
    public JsonNode broadcast(List<PushTargetVO> targetList, JsonNode config, AppPushRecord message) throws JsonProcessingException {
        PushApi pushApi = initPushApi(config);
        PushBatchDTO pushBatchDTO = new PushBatchDTO();
        for(PushTargetVO item: targetList){
            PushDTO pushDTO = createPushDTO(item, config, message);
            pushBatchDTO.addPushDTO(pushDTO);
        }
        // 进行cid单推
        ApiResult apiResult = pushApi.pushBatchByCid(pushBatchDTO);
        if (apiResult.isSuccess()) {
            ObjectMapper objectMapper = new ObjectMapper();
            return objectMapper.valueToTree(apiResult.getData());
        } else {
            throw new RuntimeException("code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
        }
    }

    public PushDTO createPushDTO(PushTargetVO target, JsonNode config, AppPushRecord message) throws JsonProcessingException {
        //根据cid进行单推
        PushDTO<Audience> pushDTO = new PushDTO<Audience>();
        // 设置推送参数，requestid需要每次变化唯一
        pushDTO.setRequestId(System.currentTimeMillis() + "");
        Settings settings = new Settings();
        pushDTO.setSettings(settings);
        //消息有效期，走厂商消息必须设置该值
        settings.setTtl(3600000);
        // 设置接收人信息
        Audience audience = new Audience();
        audience.addCid(target.getCid());
        pushDTO.setAudience(audience);

        PushMessage pushMessage = online(message); //在线推送
        pushDTO.setPushMessage(pushMessage);
        if(target.getClientPlatform().equals(AppPlatformTypeEnums.ANDROID)){
            PushChannel pushChannel = offlineAndroid(target.getClientCode(), message); //安卓离线推送
            pushDTO.setPushChannel(pushChannel);
        }
        if(target.getClientPlatform().equals(AppPlatformTypeEnums.IOS)){ //苹果离线推送
            PushChannel pushChannel = offlineIos(message);
            pushDTO.setPushChannel(pushChannel);
        }
        return pushDTO;
    }

    public PushMessage online(AppPushRecord message) throws JsonProcessingException {
        //在线走个推通道时推送的消息体
        PushMessage pushMessage = new PushMessage();
        //此格式的透传消息由 unipush 做了特殊处理，会自动展示通知栏。开发者也可自定义其它格式，在客户端自己处理。
        ObjectMapper objectMapper = new ObjectMapper();
        String transmission = objectMapper.writeValueAsString(message);
        pushMessage.setTransmission(transmission);
        return pushMessage;
    }

    public PushChannel offlineAndroid(String packageName, AppPushRecord message) {
        //设置离线推送时的消息体
        PushChannel pushChannel = new PushChannel();
        //安卓离线厂商通道推送的消息体
        AndroidDTO androidDTO = new AndroidDTO();
        Ups ups = new Ups();
        ThirdNotification thirdNotification = new ThirdNotification();
        ups.setNotification(thirdNotification);
        thirdNotification.setTitle(message.getTitle());
        thirdNotification.setBody(message.getContent());
        thirdNotification.setClickType("intent");
        //注意：intent参数必须按下方文档（特殊参数说明）要求的固定格式传值，intent错误会导致客户端无法收到消息
        String intent = initIntent(packageName, message);
        thirdNotification.setIntent(intent);
        androidDTO.setUps(ups);
        pushChannel.setAndroid(androidDTO);
        return pushChannel;
    }

    public PushChannel offlineIos(AppPushRecord message) {
        //设置离线推送时的消息体
        PushChannel pushChannel = new PushChannel();
        //ios离线apn通道推送的消息体
        Alert alert = new Alert();
        alert.setTitle(message.getTitle());
        alert.setBody(message.getContent());
        Aps aps = new Aps();
        aps.setContentAvailable(0);
        aps.setSound("default");
        aps.setAlert(alert);
        IosDTO iosDTO = new IosDTO();
        iosDTO.setAps(aps);
        iosDTO.setType("notify");
        pushChannel.setIos(iosDTO);
        return pushChannel;
    }
}
